package com.heima.wemedia.service.impl;

import ch.qos.logback.core.joran.util.beans.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.common.constants.message.WmNewsUpDownConstants;
import com.heima.common.dtos.PageResult;
import com.heima.common.dtos.ResponseResult;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.enums.NewsStatusEnum;
import com.heima.common.exception.LeadException;
import com.heima.common.threadlocal.UserThreadLocalUtils;
import com.heima.common.util.BeanHelper;
import com.heima.model.admin.dtos.NewsAuthDto;
import com.heima.model.admin.dtos.NewsAuthDelDto;
import com.heima.model.article.dtos.WmNewsDownOrUpMsgDTO;
import com.heima.model.media.dtos.WmDownOrUpDTO;
import com.heima.model.media.dtos.WmNewsDto;
import com.heima.model.media.dtos.WmNewsPageDto;
import com.heima.model.media.dtos.WmNewsPageReqDto;
import com.heima.wemedia.entity.WmNews;
import com.heima.wemedia.entity.WmNewsMaterial;
import com.heima.wemedia.entity.WmNewsVO;
import com.heima.wemedia.entity.WmUser;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.WmAuditService;
import com.heima.wemedia.service.WmNewsMaterialService;
import com.heima.wemedia.service.WmNewsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.wemedia.service.WmUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 自媒体图文内容信息表 服务实现类
 * </p>
 *
 * @author HM
 * @since 2023-05-25
 */
@Slf4j
@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    private WmNewsMaterialService newsMaterialService;

    @Autowired
    private WmAuditService auditService;

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;
    @Autowired
    private WmUserService wmUserService;

    @Override
    public ResponseResult one(Integer id) {
        if (StringUtils.isEmpty(id)){
            throw new LeadException(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNews byId = this.getById(id);
        if (StringUtils.isEmpty(byId.getWmUserId())){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        WmUser wmUser = wmUserService.getById(byId.getWmUserId());
        WmNewsVO wmNewsVO = BeanHelper.copyProperties(byId, WmNewsVO.class);
        wmNewsVO.setAuthorName(wmUser.getName());
        return ResponseResult.ok(wmNewsVO);
    }

    @Override
    public PageResult newsAuth(WmNewsPageDto dto) {
        Page<WmNews> page=new Page<>(dto.getPage(),dto.getSize());

        LambdaQueryWrapper<WmNews> queryWrapper=new LambdaQueryWrapper<>();

        queryWrapper.like(dto.getTitle()!=null,WmNews::getTitle,dto.getTitle());

        queryWrapper.orderByDesc(WmNews::getCreatedTime);



        Page<WmNews> newsPage = this.page(page, queryWrapper);

        List<WmNewsVO> collect = newsPage.getRecords().stream().map(wmNews ->
                {
                    WmUser byId = wmUserService.getById(wmNews.getWmUserId());
                    if (ObjectUtils.isEmpty(byId)){
                        throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
                    }
                    WmNewsVO wmNewsVO = BeanHelper.copyProperties(wmNews, WmNewsVO.class);
                    if (!StringUtils.isEmpty(byId.getName())){
                        wmNewsVO.setAuthorName(byId.getName());
                    }
                    return wmNewsVO;
                }
        ).collect(Collectors.toList());

        return new PageResult(dto.getPage().longValue(),dto.getSize().longValue(),newsPage.getTotal(),collect);
    }
    @Autowired
    private WmAuditService wmAuditService;

    @Override
    public void downOrUp(WmDownOrUpDTO dto) {
        WmNews newsDB = this.getById(dto.getId());
        if(newsDB == null){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        if(Objects.equals(newsDB.getEnable(), dto.getEnable())){
            // 入参的状态和数据库的状态是一样的，那么就无需更新
            return;
        }
        Long articleId = newsDB.getArticleId();
        if(articleId == null || articleId <= 0){
            throw new LeadException(AppHttpCodeEnum.WM_NEWS_NOT_PUBLISH);
        }
        Integer status = newsDB.getStatus();
        if(status == null || status != 9 ){
            throw new LeadException(AppHttpCodeEnum.WM_NEWS_NOT_PUBLISH);
        }
        // 修改状态
        WmNews toBeUpdate = new WmNews();
        toBeUpdate.setId(dto.getId());
        toBeUpdate.setEnable(dto.getEnable());
        this.updateById(toBeUpdate);
        // 发消息
        WmNewsDownOrUpMsgDTO msgDTO = new WmNewsDownOrUpMsgDTO();
        msgDTO.setArticleId(articleId);
        msgDTO.setEnable(dto.getEnable());
        kafkaTemplate.send(WmNewsUpDownConstants.WM_NEWS_UP_OR_DOWN_TOPIC, JSON.toJSONString(msgDTO));
    }
    /**
     * fegit接口调用 媒体人工审核不通过
     * @param dto
     */
    @Override
    public void authFail(NewsAuthDelDto dto) {

        WmNews byId = this.getById(dto.getId());
        if (byId == null){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        byId.setStatus(FAIL);
        byId.setReason(dto.getMsg());

        boolean b = this.updateById(byId);

    }
    /**
     * 媒体审核通过
     * @param id
     * @return
     */
    @Override
    public void authPass(Integer id) throws InvocationTargetException, IllegalAccessException {
        WmNews wmNews = this.getById(id);
        if (wmNews==null){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        Integer wmUserId = wmNews.getWmUserId();

        WmNewsDto wmNewsDto = BeanHelper.copyProperties(wmNews, WmNewsDto.class);

        wmAuditService.asyncAudit2(wmUserId,wmNewsDto);



    }

    @Override
    public PageResult<WmNews> pageQuery(WmNewsPageReqDto dto) {
        LambdaQueryWrapper<WmNews> queryWrapper = new LambdaQueryWrapper<>();
        // 前端一个状态，会对应后端多个状态，所以说，后端得用in查询
        if(dto.getStatus() != null){
            List<Integer> statusList = new ArrayList<>();
            if(dto.getStatus() == 0){
                statusList.add(0);
            }else if(dto.getStatus() == 1){
                statusList.add(1);
                statusList.add(3);
            }else if(dto.getStatus() == 2){
                statusList.add(2);
            }else if(dto.getStatus() == 4){
                statusList.add(4);
                statusList.add(8);
                statusList.add(9);
            }
            queryWrapper.in(!CollectionUtils.isEmpty(statusList), WmNews::getStatus, statusList);
        }
        queryWrapper.eq(dto.getChannelId()!=null, WmNews::getChannelId, dto.getChannelId());
        queryWrapper.like(!StringUtils.isEmpty(dto.getKeyword()), WmNews::getTitle, dto.getKeyword());
        queryWrapper.ge(dto.getBeginPubDate()!=null, WmNews::getPublishTime, dto.getBeginPubDate());
        queryWrapper.le(dto.getEndPubDate()!=null, WmNews::getPublishTime, dto.getEndPubDate());
        // 千万不要忘了当前用户这个条件
        queryWrapper.eq(WmNews::getWmUserId, UserThreadLocalUtils.getUserId());
        // 分页
        Page<WmNews> ipagew = new Page<>(dto.getPage(), dto.getSize());
        Page<WmNews> pageResponse = this.page(ipagew, queryWrapper);
        return new PageResult<WmNews>(dto.getPage(), dto.getSize(), pageResponse.getTotal(), pageResponse.getRecords());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submit(WmNewsDto dto) {
        // 保存文章, 如果id是空，就是insert，否则update
        saveArticle(dto);
        // 保存文章和素材的关联关系, 全删除，重新插入
        newsMaterialService.saveNewsMaterial(dto);
        // 如果是保存草稿
        if(dto.getDraft()){
            // 保存草稿
            return;
        }
        // 提交异步审核
        log.info("提交异步审核。。。。。");
        auditService.asyncAudit(UserThreadLocalUtils.getUserId(), dto);
    }

    public static final Integer FAIL=2;

    private void saveArticle(WmNewsDto dto) {
        // 如果id是空，就是insert，否则update
        Integer id = dto.getId();
        if(id == null){
            // insert
            WmNews toBeInsert = BeanHelper.copyProperties(dto, WmNews.class);
            toBeInsert.setWmUserId(UserThreadLocalUtils.getUserId());
            toBeInsert.setCreatedTime(new Date());
            if(dto.getDraft()){
                //如果是草稿
            }else{
                toBeInsert.setSubmitedTime(new Date());
            }
            toBeInsert.setImages(CollectionUtils.isEmpty(dto.getImages())?"":dto.getImages().stream().collect(Collectors.joining(",")));
            toBeInsert.setEnable(false);
            this.save(toBeInsert);
            dto.setId(toBeInsert.getId());
        }else{
            // update
            WmNews toBeUpdate = BeanHelper.copyProperties(dto, WmNews.class);
            if(dto.getDraft()){
                //如果是草稿
            }else{
                toBeUpdate.setSubmitedTime(new Date());
            }
            toBeUpdate.setImages(CollectionUtils.isEmpty(dto.getImages())?"":dto.getImages().stream().collect(Collectors.joining(",")));
            this.updateById(toBeUpdate);
        }
    }
}
